/**
 * FileName: NettyTestServiceImpl
 * Author: Mr.Wang
 * Date: 2025/10/16 09:20
 * Description:
 * History:
 */
package org.test.device.service.impl;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.test.device.config.netty.NettyCallback;
import org.test.device.config.netty.NettyCallbackCenter;
import org.test.device.service.NettyTestService;
import org.test.device.utils.ResultData;
import org.test.device.utils.netty.NettyClientManager;

import java.util.concurrent.TimeUnit;

import static java.util.concurrent.CompletableFuture.completedFuture;

/**
 * 〈一句话功能简述〉<br>
 * 〈service测试netty 用例〉
 *
 * @author Mr.Wang
 * @create 2025/10/16
 * @since 1.0.0
 */
@Slf4j
@Service
public class NettyTestServiceImpl implements NettyTestService {

    @Autowired
    private NettyClientManager nettyClientManager;

    @Autowired
    private NettyCallbackCenter callbackCenter;

    private static final String BUSINESS_TAG = "DEVICE_DATA_REPORT";


    /**
     * 上报设备数据
     * netty service业务代码使用用例
     *
     * @param deviceId 设备ID
     * @param data     设备数据
     * @return 是否上报成功
     * @Author: Mr.Wang
     * @Date: 2025/10/16 09:20
     */
    @Override
    public ResultData reportDeviceData(String deviceId, String data) {
        // 构建上报消息
        String originalMsg = String.format("{\"deviceId\":\"%s\",\"data\":\"%s\",\"timestamp\":%d}", deviceId, data,
                System.currentTimeMillis());

        String messageId = callbackCenter.registerCallback(
                // 业务自定义回调（成功/失败的业务逻辑）
                new NettyCallback() {
                    @Override
                    public void onSuccess(String result) {
                        // 业务自己的成功处理（如更新数据库、返回前端）
                        log.info("[NettyTestService]设备[{}]上报成功，服务端响应：{}", deviceId, result);
                    }

                    @Override
                    public void onFailure(Throwable error) {
                        // 业务自己的失败处理（如记录本地日志、触发告警）
                        log.error("[NettyTestService]设备[{}]上报失败", deviceId, error);
                    }
                },
                BUSINESS_TAG, // 传入当前业务标签
                originalMsg, // 传入原始消息
                null     // 传入最终发送消息
        );

        // 构建最终发送的消息（包含messageId和content）（嵌入messageId，服务端需带回）
        String finalMsg = String.format(
                "{\"messageId\":\"%s\",\"content\":%s}",
                messageId, originalMsg // content为原始业务消息（保持结构一致）
        );

        // 更新回调中心的finalMsg（用于超时处理）
        callbackCenter.updateFinalMsg(messageId, finalMsg);

        // 异步发送消息到服务器
        nettyClientManager.asyncInitConnection()
                .thenCompose(initSuccess -> {
                    if (!initSuccess) {
                        // 初始化失败，触发回调中心的失败逻辑
                        callbackCenter.triggerFailure(messageId, new RuntimeException("Netty连接初始化失败"));
                        return completedFuture(false);
                    }
                    return nettyClientManager.asyncSendMessage(finalMsg,5, TimeUnit.SECONDS);
                })
                .whenComplete((sendSuccess,ex)->{
                    if (ex != null) {
                        // 异常场景：触发失败回调
                        log.error("设备[{}]数据上报异常", deviceId, ex);
                        callbackCenter.triggerFailure(messageId, ex);
                    } else if (sendSuccess) {
                        // 成功场景：触发成功回调（原逻辑缺失）
                        log.info("设备[{}]数据上报成功，消息：{}", deviceId, finalMsg);
                    } else {
                        // 发送失败场景：触发失败回调
                        log.error("设备[{}]数据上报失败，消息发送未成功", deviceId);
                        callbackCenter.triggerFailure(messageId, new RuntimeException("消息发送失败"));
                    }
                });
        return new ResultData("请求已接收，正在处理上报", "async");
    }
}